﻿namespace NTLib.Core.Win.Net
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.NetworkInformation;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// Extensions used to simplify the configuration and usage of the IPAddress object.
    /// </summary>
    public static class IPAddressExtensions
    {
        #region Methods

        /// <summary>
        /// Gets the next free port.
        /// </summary>
        /// <param name="addr">The addr.</param>
        /// <param name="startPort">The start port the methods will start looking from this value. Default value 1024</param>
        /// <returns>Return the port value if one is found or -1 if fail to found one.</returns>
        public static int GetFreePort(this IPAddress addr, ushort startPort = 1024)
        {
            var prop = IPGlobalProperties.GetIPGlobalProperties();
            List<IPEndPoint> listener = new List<IPEndPoint>();

            listener.AddRange(prop.GetActiveTcpListeners());
            listener.AddRange(prop.GetActiveUdpListeners());

            var usedPort = new Queue<int>((from ep in listener
                                           let port = ep.Port
                                           where port > startPort
                                           orderby port
                                           select port).Distinct());
            var portUse = -1;

            if (usedPort.Count > 0) {
                portUse = usedPort.Dequeue();
            }

            for (; startPort < ushort.MaxValue; ++startPort)
            {
                if (startPort != portUse) {
                    return (int)startPort;
                }

                if (usedPort.Count > 0) {
                    portUse = usedPort.Dequeue();
                }
            }
            return -1;
        }

        #endregion
    }
}
